package com.hongyi.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hongyi.common.framework.constant.Constants;
import com.hongyi.common.framework.domain.LoginInfoEvent;
import com.hongyi.common.framework.domain.LoginUser;
import com.hongyi.common.framework.utils.DateUtils;
import com.hongyi.common.framework.utils.string.StringUtils;
import com.hongyi.common.framework.utils.bean.BeanUtils;
import com.hongyi.common.mybatis.page.PageData;
import com.hongyi.common.mybatis.page.PageQuery;
import com.hongyi.common.saToken.utils.LoginUtils;
import com.hongyi.system.domain.SysLoginInfo;
import com.hongyi.system.domain.SysUser;
import com.hongyi.system.domain.dto.SysLogininforDto;
import com.hongyi.system.domain.vo.SysLoginInfoVo;
import com.hongyi.system.mapper.SysLoginInfoMapper;
import com.hongyi.system.mapper.SysUserMapper;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;

import com.hongyi.system.service.ISysLoginInfoService;

import java.util.*;
import java.util.stream.Stream;

@Service
public class SysLoginInfoServiceImpl implements ISysLoginInfoService {

    @Autowired
    private SysLoginInfoMapper sysLoginInfoMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 登录记录监听
     * @param loginInfoEvent 监听事件登录信息传递内容
     */
    @EventListener
    public void recordLoginInfo(LoginInfoEvent loginInfoEvent) {
        //记录登录事件相关信息
        SysLoginInfo sysLoginInfo = new SysLoginInfo();
        BeanUtils.copyBeanProp(sysLoginInfo, loginInfoEvent);
        if (StringUtils.containsAny(loginInfoEvent.getStatus(), Constants.LOGIN_SUCCESS,Constants.LOGOUT)) {
            sysLoginInfo.setStatus(Constants.OK);
        } else if (loginInfoEvent.getStatus().equals(Constants.LOGIN_FAIL)) {
            sysLoginInfo.setStatus(Constants.FAIL);
        }
        sysLoginInfoMapper.insert(sysLoginInfo);
        //登录成功修改最后一次登录信息
        if (loginInfoEvent.getStatus().equals(Constants.LOGIN_SUCCESS)) {
            SysUser sysUser = new SysUser();
            sysUser.setLoginIp(loginInfoEvent.getIpaddr());
            sysUser.setLoginDate(loginInfoEvent.getLoginTime());
            sysUser.setUserId(loginInfoEvent.getUserId());
            sysUserMapper.updateById(sysUser);
        }
    }

    /**
     * 登录日志分页数据
     *
     * @param sysLogininforDto 日志对象
     * @param pageQuery 分页数据
     * @return 日志分页数据
     */
    @Override
    public PageData<SysLoginInfoVo> queryPageLogininforList(SysLogininforDto sysLogininforDto, PageQuery pageQuery) {
        Map<String, Object> params = sysLogininforDto.getParams();
        LambdaQueryWrapper<SysLoginInfo> lqw = new LambdaQueryWrapper<SysLoginInfo>()
                .like(StringUtils.isNotBlank(sysLogininforDto.getIpaddr()), SysLoginInfo::getIpaddr, sysLogininforDto.getIpaddr())
                .eq(StringUtils.isNotBlank(sysLogininforDto.getStatus()), SysLoginInfo::getStatus, sysLogininforDto.getStatus())
                .like(StringUtils.isNotBlank(sysLogininforDto.getUserName()), SysLoginInfo::getUserName, sysLogininforDto.getUserName())
                .between(params.get("beginTime") != null && params.get("endTime") != null,
                        SysLoginInfo::getLoginTime, params.get("beginTime"), params.get("endTime"));
        if (StringUtils.isBlank(pageQuery.getOrderByColumn())) {
            pageQuery.setOrderByColumn("info_id");
            pageQuery.setIsAsc("desc");
        }
        Page<SysLoginInfoVo> page = sysLoginInfoMapper.selectVoPage(pageQuery.build(), lqw);
        return PageData.success(page);
    }

    @Override
    public List<SysLoginInfoVo> queryLogininforList(SysLogininforDto sysLogininforDto) {
        Map<String, Object> params = sysLogininforDto.getParams();
        return sysLoginInfoMapper.selectVoList(new LambdaQueryWrapper<SysLoginInfo>()
                .like(StringUtils.isNotBlank(sysLogininforDto.getIpaddr()), SysLoginInfo::getIpaddr, sysLogininforDto.getIpaddr())
                .eq(StringUtils.isNotBlank(sysLogininforDto.getStatus()), SysLoginInfo::getStatus, sysLogininforDto.getStatus())
                .like(StringUtils.isNotBlank(sysLogininforDto.getUserName()), SysLoginInfo::getUserName, sysLogininforDto.getUserName())
                .between(params.get("beginTime") != null && params.get("endTime") != null,
                        SysLoginInfo::getLoginTime, params.get("beginTime"), params.get("endTime"))
                .orderByDesc(SysLoginInfo::getInfoId));
    }

    /**
     * 上次登录时间
     *
     * @return 时间
     */
    @Override
    public String selectLastLoginByUserName() {
        LoginUser loginUser = LoginUtils.getLoginUser();
        List<SysLoginInfoVo> sysLoginInfoVoList = sysLoginInfoMapper.selectVoList(new LambdaQueryWrapper<SysLoginInfo>()
                .eq(StringUtils.isNotEmpty(loginUser.getUsername()), SysLoginInfo::getUserName, loginUser.getUsername())
                .eq(SysLoginInfo::getStatus, Constants.SUCCESS)
                .eq(SysLoginInfo::getMsg, "登录成功").orderByDesc(SysLoginInfo::getLoginTime));
        return sysLoginInfoVoList.stream()
                .findFirst()
                .map(sysLoginInfoVo -> DateFormatUtils.format(sysLoginInfoVo.getLoginTime(), DateUtils.YYYY_MM_DD_HH_MM_SS))
                .orElse(null);
    }

    /**
     * 批量删除系统登录日志
     *
     * @param infoIds 需要删除的登录日志ID
     */
    @Override
    public int deleteLogininforByIds(Long[] infoIds) {
        return sysLoginInfoMapper.deleteBatchIds(Arrays.asList(infoIds));
    }

    /**
     * 清空系统登录日志
     */
    @Override
    public void cleanLogininfor() {
        sysLoginInfoMapper.delete(new LambdaQueryWrapper<>());
    }
}
